package com.mate.cloud.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mate.cloud.common.config.PropertyConfig;
import com.mate.cloud.core.util.ObjectUtil;
import com.mate.cloud.core.util.StringUtils;
import com.mate.cloud.constant.RedisConstans;
import com.mate.cloud.constant.UserExceptionCodeEnum;
import com.mate.cloud.dataobject.UserInfo;
import com.mate.cloud.dto.UserInfoDTO;
import com.mate.cloud.exception.UserBusinessException;
import com.mate.cloud.mapper.UserInfoMapper;
import com.mate.cloud.service.UserService;
import com.mate.cloud.util.KeyUtils;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserService {

    @Resource
    UserInfoMapper userInfoMapper;


    @Resource
    RedisTemplate redisTemplate;


    @Override
    @Transactional
    public UserInfoDTO registerByEmail(UserInfoDTO userInfo) {
        LambdaQueryWrapper<UserInfo> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(StringUtils.isNotEmpty(userInfo.getEmail()), UserInfo::getEmail, userInfo.getEmail())
                .eq(StringUtils.isNotEmpty(userInfo.getName()), UserInfo::getName, userInfo.getName());
        //校验邮箱是否被注册过
        UserInfo info = userInfoMapper.selectOne(queryWrapper);
        if (ObjectUtil.isNotEmpty(info)) {
            //  已经注册过了,抛出已注册异常
            String property = PropertyConfig.getProperty(UserExceptionCodeEnum.EMAIL_ALREADY_REGISTER.getCode(), "请");
            log.error("============property============{}", property);
            throw new UserBusinessException(UserExceptionCodeEnum.EMAIL_ALREADY_REGISTER.getCode());
        }
        //  没有被注册过，则存入数据库
        UserInfo user = new UserInfo();
        BeanUtils.copyProperties(userInfo, user);
        userInfoMapper.insert(user);
        if (ObjectUtil.isEmpty(user)) {
            throw new UserBusinessException(UserExceptionCodeEnum.REGISTER_FAIL.getCode());
        }
        UserInfoDTO userInfoDTO = new UserInfoDTO();
        BeanUtils.copyProperties(user, userInfoDTO);

        return userInfoDTO;
    }

    @Override
    @Transactional
    public Integer updateInfo(UserInfo userInfo) {
        return userInfoMapper.insert(userInfo);
    }

    private UserInfoDTO convertToDTO(UserInfo user) {

        UserInfoDTO userInfoDTO = new UserInfoDTO();
        if (ObjectUtil.isNotEmpty(user)) {
            BeanUtils.copyProperties(user, userInfoDTO);
            return userInfoDTO;
        }
        return userInfoDTO;
    }

    @Override
    public UserInfoDTO loginByEmail(String email, String password) {

//        LambdaQueryWrapper<UserInfo> queryWrapper = Wrappers.lambdaQuery();
//        queryWrapper.eq(StringUtils.isNotEmpty(email), UserInfo::getEmail, email)
//                .eq(StringUtils.isNotEmpty(password), UserInfo::getPassword, password);
        UserInfo userInfo = userInfoMapper.selectOne(new LambdaQueryWrapper<UserInfo>()
                .eq(StringUtils.isNotEmpty(email), UserInfo::getEmail, email)
                .eq(StringUtils.isNotEmpty(password), UserInfo::getPassword, password));
        if (ObjectUtil.isEmpty(userInfo)) {
            throw new UserBusinessException(UserExceptionCodeEnum.EMAIL_NOT_EXIST.getCode());
        }
        if (!userInfo.getPassword().equals(password)) {
            throw new UserBusinessException(UserExceptionCodeEnum.PASSWORD_ERROR.getCode());
        }
        // 生成 token 并保存在 Redis 中
        String token = KeyUtils.genUniqueKey();
        // 将token存储在 Redis 中。键是 TOKEN_用户id, 值是token
        redisTemplate.opsForValue().set(String.format(RedisConstans.TOKEN_TEMPLATE, userInfo.getId()), token, 2L, TimeUnit.HOURS);
        UserInfoDTO userInfoDTO = convertToDTO(userInfo);
        userInfoDTO.setToken(token);
        return userInfoDTO;
    }

    @Override
    public UserInfo loginByTel(String tel, String password) {
        return null;
    }

    @Override
    public void logout(String userId) {
        // 从 Redis 中删除当前用户对应的key
        String key = String.format(RedisConstans.TOKEN_TEMPLATE, userId);
        redisTemplate.delete(key);
    }

    @Override
    public UserInfo findById(String id) {
        return userInfoMapper.selectById(id);
    }

    @Override
    @Transactional
    public UserInfo resetPassword(String id, String oldPassword, String newPassword) {
        UserInfo userInfo = userInfoMapper.selectById(id);
        if (ObjectUtil.isEmpty(userInfo)) {
            throw new UserBusinessException(UserExceptionCodeEnum.CANNOT_FIND_USER_INFO.getCode());
        }
        String password = userInfo.getPassword();
        //先校验旧密码
        if (!password.equalsIgnoreCase(oldPassword)) {
            throw new UserBusinessException(UserExceptionCodeEnum.PASSWORD_ERROR.getCode());
        }
        //密码校验通过保存新密码
        userInfo.setPassword(newPassword);
        updateInfo(userInfo);

        return userInfo;
    }

}
